package com.zfy.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zfy.tingshu.common.constant.RedisConstant;
import com.zfy.tingshu.common.rabbit.constant.MqConst;
import com.zfy.tingshu.common.rabbit.service.RabbitService;
import com.zfy.tingshu.model.user.UserInfo;
import com.zfy.tingshu.model.user.UserPaidAlbum;
import com.zfy.tingshu.model.user.UserPaidTrack;
import com.zfy.tingshu.user.mapper.UserInfoMapper;
import com.zfy.tingshu.user.mapper.UserPaidAlbumMapper;
import com.zfy.tingshu.user.mapper.UserPaidTrackMapper;
import com.zfy.tingshu.user.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfy.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitService rabbitService;
    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

	@Override
	public Map<String, Object> wxLogin(String code) {
		WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
		try {
			wxMaJscode2SessionResult = wxMaService.jsCode2SessionInfo(code);
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}
		//	openid: 每个人的微信都对应的一个微信标识！
		String openid = wxMaJscode2SessionResult.getOpenid();
		//	利用openid 实现登录或注册功能;
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//	判断对象是否为空
		if (null == userInfo) {
			//	说明要注册： 本质赋值;
			userInfo = new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("听友:" + System.currentTimeMillis());
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/zfy.jpg");
			//	保存数据到数据库;
			userInfoMapper.insert(userInfo);
			//  在此需要给当前注册的用户进行初始化充值;  同步：异步：mq 发送消息;
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_USER_REGISTER,userInfo.getId());
		}
		//	说明要登录： 将数据存储到redis，与返回token;
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//	组成缓存的key;
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		//  存储数据;
		redisTemplate.opsForValue().set(userLoginKey, userInfo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//  返回数据;
		HashMap<String, Object> map = new HashMap<>();
		map.put("token", token);
		return map;
	}

	@Override
	public UserInfoVo getUserInfoVoByUserId(Long userId) {
		//获取到用户信息对象
		UserInfo userInfo = this.getById(userId);
		//创建UserInfoVo 对象
		UserInfoVo userInfoVo = new UserInfoVo();
		BeanUtils.copyProperties(userInfo,userInfoVo);
		return userInfoVo;
	}

    @Override
    public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
        //创建map 集合
		Map<Long, Integer> collect = trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 0));
		//判断用户是否购买过专辑：user_paid_album
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>()
				.eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		if (null!=userPaidAlbum){
			//当前这个用户购买了专辑；
			return trackIdList.stream().collect(Collectors.toMap(trackId->trackId,trackId->1));
		}
		//查询用户购买声音的集合列表
		List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>()
				.eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList));
		//这个列表，可能是空
		if (!CollectionUtils.isEmpty(userPaidTracks)){
			//购买过声音；
			userPaidTracks.stream().forEach(userPaidTrack -> {
				collect.put(userPaidTrack.getTrackId(),1);
			});
		}
		//返回数据
		return collect;
	}
}
